
#include <algorithm>
#include <fstream>
#include <sstream>
#include <string>
#include "deformationShape_FSGPU_L1.h"

#include "fbocheck.h"

namespace MLS {
   
///
/// Returns 1 if an OpenGL error occurred, 0 otherwise.
static int gl_error_check() {
   
   GLenum glErr;
   int retCode = 0;
   
   glErr = glGetError();
   while (glErr != GL_NO_ERROR) {
      cerr << "glError : " << gluErrorString(glErr) << "\n";
      retCode = 1;
      glErr = glGetError();
   }
   return retCode;
}

DeformationShape_FSGPU_L1::DeformationShape_FSGPU_L1() {
   Deformation::Deformation();
   
   shaderFileName = "../mlsrigiddeformer.fs.L0.h";
}

DeformationShape_FSGPU_L1::~DeformationShape_FSGPU_L1() {
   
}
   
void DeformationShape_FSGPU_L1::setting(Shape3D *m, const MLS::Constraints *constraints) {
   cout<<"DeformationShape_FSGPU_L1::setting()"<<endl;
   // Call the setting function of the parent class
   DeformationShape_FSGPU::setting(m, constraints);
   
   // Compute the weights table
   if (WeightsTable != 0) delete []WeightsTable;
   
   uint nminusone = std::count(constraints->ids.begin(), constraints->ids.end(), -1);
   if (nminusone == 0) // If all constraints are associated with joints
      WeightsTable = MLS::compute_WeightsTable(model, constraints);
   else if (nminusone < constraints->ids.size()) // If constraints are represented a trihedron
      WeightsTable = MLS::compute_WeightsTable_Trihedrons(model, constraints);
   else
      WeightsTable = 0;
   
   cout<<"DeformationShape_FSGPU_L1::setting() 1111"<<endl;
   
   //~ Deformation::initialize();
   
   assert(!gl_error_check());  // testing all ok
   
   glActiveTexture(GL_TEXTURE10);
   glGenTextures(1, &texWeightsTable);
   glBindTexture(GL_TEXTURE_3D, texWeightsTable);
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexImage3D(GL_TEXTURE_3D, 0, GL_LUMINANCE32F_ARB, quadSize, quadSize, constraints->size(), 0, 
                GL_RED, GL_FLOAT, WeightsTable);
   
   kernel.use(true);
   kernel.set_uniform("WeightsTable", 10);
   kernel.use(false);
   
   //~ checkGLerrors("saindo dos settings");
   assert (!gl_error_check());  // testing all ok
}

/*
void DeformationShape_FSGPU_L1::execute_deformation(const MLS::Constraints *constraints) {
   
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
   kernel.use(true);
   
   ///< It transfers the Q positions to the GPU memory
   glActiveTexture(GL_TEXTURE4);
   glBindTexture(GL_TEXTURE_RECTANGLE_NV, texQpoints);
   glTexSubImage2D(GL_TEXTURE_RECTANGLE_NV,0,0,0,1,
                   constraints->size(),GL_RGB,GL_FLOAT,&constraints->positions[0][0]);
   //~ checkGLerrors("sending the Q positions to GPU");
   //~ kernel_mlsrigid.set_uniform("Q", 4);
   
   glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
   //~ glDrawBuffers(2, fbo_buffers_1);
   
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0.0, quadSize, 0.0, quadSize);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glViewport(0, 0, (GLsizei) quadSize, (GLsizei) quadSize);
   
   glBegin(GL_QUADS);
      glTexCoord2d(0,0);        glVertex2f(0, 0);
      glTexCoord2d(1.0,0);      glVertex2f(quadSize, 0);
      glTexCoord2d(1.0,1.0);    glVertex2f(quadSize, quadSize);
      glTexCoord2d(0,1.0);      glVertex2f(0, quadSize);
   glEnd();
   
   glFinish();
   
   glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
   glReadPixels(0, 0, quadSize, quadSize, GL_RGB, GL_FLOAT, model->vpositions);
   
   kernel.use(false);
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
   
   //~ glPopAttrib();
   /// The viewport modelview/projection matrix must be newly sets by the main program !
}
*/

} // end MLS namespace
